/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package classcreator.classfillers;

import classcreator.abstractclasses.AbstractClass;
import classcreator.abstractclasses.AbstractFK;
import classcreator.abstractclasses.AbstractProperty;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Samus
 */
public class ABMSent {

    private static ABMSent instance = new ABMSent();

    public static ABMSent getInstance() {
        return instance;
    }

    private ABMSent() {
    }

    public void createSentences(AbstractClass clase) {
        clase.setSQLSentenceCreate(SQLCreaSentence(clase));
        clase.setSQLSentenceAdd(SQLAddSentence(clase));
        clase.setSQLSentenceDelete(SQLDelSentence(clase));
        clase.setSQLSentenceModify(SQLModSentence(clase));
        if (clase.getFks().size() > 0) {
            clase.setSQLSentenceFK(agregarFKs(clase.getFks(), clase.getNombreclase()));
        }
    }

    public String SQLCreaSentence(AbstractClass clase) {
        String res = "create table ";
        res += clase.getNombreclase() + "(";
        int i = 0;
        ArrayList<AbstractProperty> pks = new ArrayList<AbstractProperty>();
        if (clase.isAutoPk()) {
            res += "autogenid int(10) auto_increment, ";
        }
        while (i < clase.getProperties().size()) {
            if (!clase.getProperties().get(i).getName().equals("autogenid")) {
                res += clase.getProperties().get(i).getName() + " " + properties(clase.getProperties().get(i)) + " not null";
                if (i != clase.getProperties().size() - 1) {
                    res += ", ";
                }
            }
            if (clase.getProperties().get(i).isPk()) {
                pks.add(clase.getProperties().get(i));
            }
            i++;
        }
        res = agregarPK(pks, res);
        return res;
    }

    public String SQLAddSentence(AbstractClass clase) {
        String res = "insert into " + clase.getNombreclase() + " (";
        String resaux = "";
        int i = 0;
        while (i < clase.getProperties().size()) {
            if (!clase.getProperties().get(i).getName().equals("autogenid")) {
                res += clase.getProperties().get(i).getName();
                resaux += "new" + clase.getProperties().get(i).getName();
                if (i != clase.getProperties().size() - 1) {
                    res += ", ";
                    resaux += ", ";
                }
            }
            i++;
        }
        res += ") values (" + resaux + ")";
        return res;
    }

    public String SQLDelSentence(AbstractClass clase) {
        String res = "delete from " + clase.getNombreclase() + " where ";
        for (int i = 0; i < clase.getProperties().size(); i++) {
            if (clase.getProperties().get(i).isPk()) {
                res += clase.getProperties().get(i).getName() + " = new" + clase.getProperties().get(i).getName();
                if (clase.readPKs().size() > 1) {
                    if (i != clase.getProperties().size() - 1) {
                        res += " and ";
                    }
                }
            }
        }
        return res;
    }

    public String SQLModSentence(AbstractClass clase) {
        String res = "update " + clase.getNombreclase() + " set ";
        String resaux = " where ";
        for (int i = 0; i < clase.getProperties().size(); i++) {
            if (!clase.getProperties().get(i).isPk()) {
                String aux = clase.getProperties().get(i).getName();
                res += "(" + aux + ", new" + aux + ")";
            } else {
                resaux += clase.getProperties().get(i).getName() + " = new" + clase.getProperties().get(i).getName();
                if (clase.readPKs().size() > 1) {
                    if (i != clase.getProperties().size() - 1) {
                        resaux += " and ";
                    }
                }
            }
        }
        res += resaux;
        return res;
    }

    public String properties(Object o) {
        //Método que devuelve el tipo de dato según si se le pase una FK o una property.
        String res = "";
        if (o instanceof AbstractProperty) {
            AbstractProperty prop = (AbstractProperty) o;
            res = Sorters.getInstance().propSortSent(prop);
        } else if (o instanceof AbstractFK) {
            AbstractFK ab = (AbstractFK) o;
            AbstractProperty prop = new AbstractProperty();
            prop.setName(ab.getProperty());
            prop.setType(ab.getType());
            prop.setPk(false);
            res = Sorters.getInstance().propSortSent(prop);
        }
        return res;
    }

    public String agregarPK(ArrayList<AbstractProperty> props, String res) {
        res += ", primary key (";
        for (int i = 0; i
                < props.size(); i++) {
            res += props.get(i).getName();
            if (i < props.size() - 1) {
                res += ", ";
            }
        }
        res += "))";
        return res;
    }

    public String agregarFKs(List<AbstractFK> fks, String clase) {
        // para las FKs de misma tabla, se comparte la cláusula Foreign Key.
        String fktxt = " add foreign key (";
        String reftxt = " references ";
        String res = "alter table " + clase;
        int i = 0;
        if (fks.size() > 1) {
            while (i < fks.size() - 1) {
                AbstractFK fkpointer = fks.get(i);
                String refaux = "";
                res += fktxt;
                while (fks.get(i).getRefTable().equals(fkpointer.getRefTable()) && i < fks.size() - 1) {
                    res += fks.get(i).getProperty();
                    refaux += fks.get(i).getFk();
                    if (i != fks.size() - 1) {
                        if (fks.get(i + 1).getRefTable().equals(fkpointer.getRefTable())) {
                            res += ", ";
                            refaux += ", ";
                        }
                    }
                    i++;
                }
                if (i == fks.size() - 1) {
                    res += fks.get(i).getProperty();
                    refaux += fks.get(i).getFk();
                }
                res += ")" + reftxt + fkpointer.getRefTable() + "(" + refaux + ")";
            }
        } else {
            res += fktxt;
            AbstractFK fk = fks.get(0);
            res += fk.getProperty() + ")" + reftxt + fk.getRefTable() + "(" + fk.getFk() + ")";
        }
        return res;
    }
}
